﻿#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//1.获得文本文件的行数；
int getFileLines(FILE* file)
{
	if (NULL == file)
	{
		return -1;
	}
	char buf[1024] = { 0 };
	int lines = 0;
	while (fgets(buf, 1024, file) != NULL)
	{
		++lines;
	}
	//10.恢复文件指针指向文件的起始位置；执行这个方法后，要将文件指针file已经指到了文件的末尾，下面读取文件就会
		//全部读取到null，所以要将文件指针file重新指到0位置；
	fseek(file, 0, SEEK_SET);

	return lines;
}
//6.读取文件数据；
void readFileData(FILE* file, int lines, char** content)
{
	if (NULL == file)
	{
		return;
	}
	if (NULL == content)
	{
		return;
	}
	if (lines <= 0)
	{
		return;
	}
	//7.创建缓冲区；
	char buf[1024] = { 0 };
	int index = 0;
	while (fgets(buf, 1024, file) != NULL)
	{
		//11.输出时多了一行空格，在此去掉\n；
		//printf("8.输出读取到一行内容buf：%s", buf);//aaaaaaaaaaaaaaaaa, ... ,fffffffffffff

		//12.获取到该行字符数的长度，此时要+1，是为了存字符串，加上\0。strlen求出来是实际长度，不包含\0。
		int curLineLen = strlen(buf) + 1;
		//13.给当前行分配堆内存；
		char* lineContent = malloc(sizeof(char) * curLineLen);
		//14.将该行数据拷贝到堆内存空间中；
		strcpy(lineContent, buf);

		//15.二级指针content加上索引，就是一级指针lineContent的地址，表示指向堆内存数据；
		content[index++] = lineContent;
		memset(buf, 0, 1024);
	}
}
void showFileContents(char** contents, int lines)
{
	for (int i = 0; i < lines; ++i)
	{
		printf("17.输出第%d行内容：%s", i + 1, contents[i]);//17.输出第1行内容：aaaaaaaaaaaaaaaaa , ... ,
	}
}
//18.释放文件数据内存；
void freeFileSpace(char** contents, int lines)
{
	for (int i = 0; i < lines; ++i)
	{
		if (contents[i] != NULL)
		{
			free(contents[i]);
			contents[i] = NULL;
		}
	}
	free(contents);
	contents = NULL;
}
void testSecondPointerExercise()
{
	//4.打开文件；
	FILE* file = fopen("E:\\file\\SecondPointerExercise.txt", "r");
	if (NULL == file)
	{
		printf("2.打开文件SecondPointerExercise.txt失败！\n");
		return;
	}
	//5.统计文件行数；
	//int lines = 10;
	int lines = getFileLines(file);
	printf("3.输出文件SecondPointerExercise.txt的行数lines为：%d\n", lines);//6

	char** pContents = malloc(sizeof(char*) * lines);
	//9.读取文件内容；
	readFileData(file, lines, pContents);

	//20.关闭文件，读完后就可以关闭了；
	fclose(file);
	file = NULL;

	//16.打印文件内容；
	showFileContents(pContents, lines);

	//19.释放文件数据；
	freeFileSpace(pContents, lines);
}

//main200：二级指针练习文本文件读取内容
int main200()
{
	testSecondPointerExercise();

	system("pause");
	return EXIT_SUCCESS;
}